﻿using System;
using System.Collections.Generic;
using System.Linq;
using mebc.reflection;

namespace mebc
{
    public interface IPart : IFunctionalUnit
    {
        void Process<T>(Action<T> messageHandler);
        void Send<T>(T payload);
    }


    public abstract class APartOf<T> : Part
    {
        protected APartOf() { Process<T>(Process); }

        public abstract void Process(T message);
    }


    public class Part : FunctionalUnit, IPart
    {
        protected readonly Dictionary<Type, Delegate> _inputHandlers = new Dictionary<Type, Delegate>();


        public override void  InputPipe(IMessage message)
        {
            if (_inputHandlers.ContainsKey(message.MessageType))
                _inputHandlers[message.MessageType].DynamicInvoke(message.Value);
            else
                throw new InvalidCastException("Missing handler for type: " + message.MessageType.FullName);
        }


        public void Process<T>(Action<T> messageHandler)
        {
            _inputHandlers.Add(typeof(T), messageHandler);
        }


        public void Send<T>(T payload)
        {

            base.SendMessage(new Message<T> { Value = payload });
        }


        public override MetaData GetMetaData()
        {
            var md = new MetaData {
                                    Id = this.GetHashCode().ToString(),
                                    Type = this.GetType(),
                                    InputPins = _inputHandlers.Keys
                                  };
            return md;
        }
    }
}